
#include <BMesh>
#include <BGeometry>
#include "../LineStripe.h"
#include "EdgePicker.h"

EdgePicker::EdgePicker()
{
	_camera = 0;
}
EdgePicker::~EdgePicker()
{

}

void EdgePicker::setCamera(BCamera* camera)
{
	_camera = camera;
}
BCamera* EdgePicker::camera() const
{
	return _camera;
}

void EdgePicker::reset()
{

}
void EdgePicker::pick(const BLine& line, BMesh* mesh)
{
	bool cullback = mesh->cullback();
	const BVectorArray* vertices = mesh->vertices();
	if (const BFaceArray* faces = mesh->faces())
	{
		BPolygon polygon;
		for (int i = 0; i < faces->size(); i++)
		{
			const BFace& face = (*faces)[i];
			const BVector& va = (*vertices)[face.a()];
			const BVector& vb = (*vertices)[face.b()];
			const BVector& vc = (*vertices)[face.c()];
			BReal ratio = 0;
			if (line.intersect(va, vb, vc, ratio, cullback))
			{

			}
		}
	}
	else
	{
		BPolygon polygon;
		for (int i = 0; i < vertices->size(); i += 3)
		{
			const BVector& va = (*vertices)[i];
			const BVector& vb = (*vertices)[i + 1];
			const BVector& vc = (*vertices)[i + 2];
			BReal ratio = 0;
			if (line.intersect(va, vb, vc, ratio, cullback))
			{

			}
		}
	}
}
void EdgePicker::pick(const BLine& line, BGeometry* geometry)
{
	BVectorArray* vertices = geometry->vertices();
	if (!vertices)
		return;

	bool cullback = geometry->cullback();
	for (int i = 0; i < geometry->elementCount(); i++)
	{
		BElement* element = geometry->element(i);
		Primitive primitive = element->primitive();
		BIntArray* indices = element->indices();
		if (indices)
		{
			int size = indices->size();
			if (element->primitive() == Primitive_Triangles)
			{
				for (int i = 0; i < size; i += 3)
				{
					int ia = (*indices)[i];
					int ib = (*indices)[i + 1];
					int ic = (*indices)[i + 2];
					const BVector& va = (*vertices)[ia];
					const BVector& vb = (*vertices)[ib];
					const BVector& vc = (*vertices)[ic];
					BReal ratio;
					if (line.intersect(va, vb, vc, ratio, cullback))
					{
						BVector point = line.vertex(ratio);
						BReal unit = _camera->unit(point * this->matrix());
						BReal distAB = line.distance(BLine(va, vb));
						BReal distBC = line.distance(BLine(vb, vc));
						BReal distCA = line.distance(BLine(vc, va));
						if (distAB < distBC && distAB < distCA)
						{
							BReal pixlen = distAB / unit;
							if (pixlen < 10)
							{
								BPickHit* hit = new BPickHit(Primitive_Lines);
								hit->setRatio(ratio);
								hit->setPoint(point);
								hit->setShape(geometry);
								hit->setElement(element);
								hit->setProperty("line", BLine(va, vb));
								hit->setProperty("begin", ia);
								hit->setProperty("end", ib);
								this->record(hit);
							}
							continue;
						}
						if (distBC < distAB && distBC < distCA)
						{
							BReal pixlen = distBC / unit;
							if (pixlen < 10)
							{
								BPickHit* hit = new BPickHit(Primitive_Lines);
								hit->setRatio(ratio);
								hit->setPoint(point);
								hit->setShape(geometry);
								hit->setElement(element);
								hit->setProperty("line", BLine(vb, vc));
								hit->setProperty("begin", ib);
								hit->setProperty("end", ic);
								this->record(hit);
							}
							continue;
						}
						if (distCA < distAB && distCA < distBC)
						{
							BReal pixlen = distCA / unit;
							if (pixlen < 10)
							{
								BPickHit* hit = new BPickHit(Primitive_Lines);
								hit->setRatio(ratio);
								hit->setPoint(point);
								hit->setShape(geometry);
								hit->setElement(element);
								hit->setProperty("line", BLine(vc, va));
								hit->setProperty("begin", ic);
								hit->setProperty("end", ia);
								this->record(hit);
							}
							continue;
						}
					}
				}
			}
			if (element->primitive() == Primitive_TriangleStrip)
			{
				for (int i = 0; i < size; i++)
				{
					int ia = (*indices)[i];
					int ib = (*indices)[i + 1];
					int ic = (*indices)[i + 2];
					const BVector& va = (*vertices)[ia];
					const BVector& vb = (*vertices)[ib];
					const BVector& vc = (*vertices)[ic];
					BReal ratio = 0;
					if (line.intersect(va, vb, vc, ratio, cullback))
					{
						return;
					}
				}
			}
			if (element->primitive() == Primitive_Quads)
			{
				for (int i = 0; i < size; i += 4)
				{
					int ia = (*indices)[i];
					int ib = (*indices)[i + 1];
					int ic = (*indices)[i + 2];
					int id = (*indices)[i + 3];
					const BVector& va = (*vertices)[ia];
					const BVector& vb = (*vertices)[ib];
					const BVector& vc = (*vertices)[ic];
					const BVector& vd = (*vertices)[id];
					BReal ratio = 0;
					if (line.intersect(BQuad(va, vb, vc, vd), ratio, cullback))
					{
						return;
					}
				}
			}
			continue;
		}
		const BPieceArray* pieces = element->pieces();
		if (pieces)
		{
			int size = pieces->size();
			if (element->primitive() == Primitive_Triangles)
			{
				for (int i = 0; i < size; i += 3)
				{
					int ia = (*pieces)[i].v();
					int ib = (*pieces)[i + 1].v();
					int ic = (*pieces)[i + 2].v();
					const BVector& va = (*vertices)[ia];
					const BVector& vb = (*vertices)[ib];
					const BVector& vc = (*vertices)[ic];
					BReal ratio = 0;
					if (line.intersect(va, vb, vc, ratio, cullback))
					{
					}
				}
				continue;
			}
			if (element->primitive() == Primitive_Quads)
			{
				for (int i = 0; i < size; i += 4)
				{
					int ia = (*pieces)[i].v();
					int ib = (*pieces)[i + 1].v();
					int ic = (*pieces)[i + 2].v();
					int id = (*pieces)[i + 3].v();
					const BVector& va = (*vertices)[ia];
					const BVector& vb = (*vertices)[ib];
					const BVector& vc = (*vertices)[ic];
					const BVector& vd = (*vertices)[id];
					BReal ratio;
					if (line.intersect(BQuad(va, vb, vc, vd), ratio, cullback))
					{
					}
				}
				continue;
			}

			continue;
		}
		int first = element->first();
		int count = element->count();
		if (element->primitive() == Primitive_Triangles)
		{
			for (int i = first; i < count; i += 3)
			{
				const BVector& va = (*vertices)[i];
				const BVector& vb = (*vertices)[i + 1];
				const BVector& vc = (*vertices)[i + 2];
				BReal ratio = 0;
				if (line.intersect(va, vb, vc, ratio, cullback))
				{
					continue;
				}
			}
			continue;
		}
		if (element->primitive() == Primitive_TriangleStrip)
		{
			for (int i = first; i < count; i++)
			{
				const BVector& va = (*vertices)[i];
				const BVector& vb = (*vertices)[i + 1];
				const BVector& vc = (*vertices)[i + 2];
				BReal ratio = 0;
				if (line.intersect(va, vb, vc, ratio, cullback))
				{
					return;
				}
			}
			continue;
		}
		if (element->primitive() == Primitive_Quads)
		{
			for (int i = first; i < count; i += 4)
			{
				const BVector& va = (*vertices)[i];
				const BVector& vb = (*vertices)[i + 1];
				const BVector& vc = (*vertices)[i + 2];
				const BVector& vd = (*vertices)[i + 3];
				BReal ratio = 0;
				if (line.intersect(BQuad(va, vb, vc, vd), ratio, cullback))
				{
					return;
				}
			}
			continue;
		}
	}
}
